﻿/*
孪生素数 
Time Limit:200MS  Memory Limit:32768K


Description:
能在指定的整数区间内，快速算出有多少对孪生素数，则是好样的。所谓孪生素数即数值相差为2的素数，例如3和5是孪生素数。 

Input:
有若干整数对a,b（1<a<b<2^19）。 
Output:
输出在a,b区间内孪生素数的个数。每组整数对都对应一行结果。 
Sample Input:
1  28
20 100
Sample Output:
4
4
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
unsigned main()
{
	vector<unsigned> vlo, vhi;
	for (unsigned a, b; cin>>a>>b;)
	{
		if(a>b)swap(a, b);
		vlo.push_back(a);
		vhi.push_back(b);
	}
	
	unsigned maximum=*max_element(vhi.begin(), vhi.end());
	
	vector<unsigned> primes;
	primes.push_back(2);
	primes.push_back(3);
	primes.push_back(5);
	
	unsigned integer=5;
	unsigned gap=2;
	while (true)
	{
		integer+=gap;
		if(integer>maximum)break;
		gap=6-gap;
		bool is_prime=true;
		for (unsigned i=2; primes[i]*primes[i]<=integer && is_prime; i++)
			if(0==integer%primes[i])
				is_prime=false;
			if(is_prime)
				primes.push_back(integer);
	}
//	copy(primes.begin(), primes.end(), ostream_iterator<unsigned>(cout, " "));

	for (vector<unsigned>::size_type i=0, size=vlo.size(); i<size; ++i)
	{
		vector<unsigned>::iterator pos1=lower_bound(primes.begin(), primes.end(), vlo[i]);
		if(pos1==primes.end())
			continue;

		unsigned prime=*pos1;
		unsigned counter=0U;
		while (prime<=vhi[i])
		{				
			prime=*pos1;
			vector<unsigned>::iterator pos2=pos1+1;				
			if((prime+2)==(*pos2))
			{
				pos1=pos2+1;	
				++counter;
				//cout<<prime<<", "<<(prime+2)<<endl;
			}
			else
				++pos1;					
		}
	
		cout<<counter<<endl;
	}
		
	return 0;
}

/*
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
unsigned main()
{
	vector<unsigned> vlo, vhi;
	for (unsigned a, b; cin>>a>>b;)
	{
		if(a>b)swap(a, b);
		vlo.push_back(a);
		vhi.push_back(b);
	}

	unsigned maximum=*max_element(vhi.begin(), vhi.end());
	
	vector<unsigned> primes;
	primes.push_back(2);
	primes.push_back(3);
	primes.push_back(5);
	
	unsigned integer=5;
	unsigned gap=2;
	while (true)
	{
		integer+=gap;
		if(integer>maximum)break;
		gap=6-gap;
		bool is_prime=true;
		for (unsigned i=2; primes[i]*primes[i]<=integer && is_prime; i++)
			if(0==integer%primes[i])
				is_prime=false;
			if(is_prime)
				primes.push_back(integer);
	}
	copy(primes.begin(), primes.end(), ostream_iterator<unsigned>(cout, " "));
	cout<<endl;
	for (vector<unsigned>::size_type i=0, size=vlo.size(); i<size; ++i)
	{
		vector<unsigned>::iterator pos1=primes.begin();
		unsigned counter=0U;
		while (true)
		{
			pos1=lower_bound(pos1, primes.end(), vlo[i]);
			unsigned prime=*pos1;
			//if(pos1==primes.end())
			if(prime>vhi[i])
			{
				cout<<counter<<endl;
				break;
			}
			else{
				
				vector<unsigned>::iterator pos2=pos1+1;				
				if(binary_search(pos2, primes.end(), prime+2))
				{
					pos1=pos2+1;	
					++counter;
					cout<<prime<<", "<<(prime+2)<<endl;
				}
				else
					++pos1;
			}		
		}

	return 0;
}
*/